use std::sync::Arc;

use crate::{custom::CustomView, obj_ref_to_ptr};
use core_graphics::{CGPoint, CGRect, CGSize};
use foundation::NSData;
use metal::MTLDevice;
use objc::{
  msg_send,
  runtime::{Object, BOOL, NO},
  sel, sel_impl,
};
use objc_derive::{objc_impl, selector_impl};
use uikit::{UIColor, UIImage, UIImageView, UILabel, UIView, UIViewController};

pub const LOGO: &[u8] = include_bytes!("../../resources/rust_logo.png");

pub(crate) struct MainViewController {}

impl MainViewController {
  pub(crate) fn new() -> Self {
    Self {}
  }
}

#[objc_impl(UIViewController)]
impl MainViewController {
  #[selector_impl("loadView")]
  fn load_view(&self, this: &Object) {
    let view = Arc::new(CustomView::new());
    let view = UIView(view.init_objc_proxy_obj());
    view.set_translates_autoresizing_mask_into_constraints(NO);

    let id = obj_ref_to_ptr(this);
    let ui_view_controller = UIViewController(id);
    ui_view_controller.set_view(view);

    println!("MainViewController load view");
  }

  #[selector_impl("viewDidLoad")]
  fn view_did_load(&self, this: &Object) {
    println!("MainViewController did load");
    unsafe {
      let id = obj_ref_to_ptr(this);
      let ui_view_controller = UIViewController(id);

      ui_view_controller.view().set_background_color(UIColor::white_color());

      let label = {
        let label = UILabel::alloc();
        let origin = CGPoint { x: 0., y: 100. };
        let label: UILabel = msg_send!(label, init);
        label.set_center(origin);
        if let Some(device) = MTLDevice::system_default() {
          label.set_text(device.name());
        } else {
          label.set_text("Hello From Rust".into());
        }
        label.size_to_fit();
        label
      };
      let label_ui_view = UIView(label.0);
      label_ui_view.set_background_color(UIColor::red_color());

      let image = {
        let data = NSData::data_with_bytes_length(LOGO, LOGO.len());
        UIImage::image_with_data(data)
      };

      let image_view = {
        let image_view = UIImageView::alloc();
        let image_view: UIImageView = image_view.init_with_image(image);
        image_view
      };

      let image_view = UIView(image_view.0);
      let frame = CGRect {
        origin: CGPoint { x: 0., y: 150. },
        size: CGSize {
          width: 100.,
          height: 100.,
        },
      };
      image_view.set_frame(frame);
      ui_view_controller.view().add_subview(label_ui_view);
      ui_view_controller.view().add_subview(image_view);
    }
  }

  #[selector_impl("viewDidAppear:")]
  fn view_did_appear(&self, _this: &Object, _animated: BOOL) {
    println!("MainViewController view did appear");
  }
}
